package com.peas.platform.module.icims.base.mdm.domain.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.peas.platform.common.core.configuration.RequestContextUtil;
import com.peas.platform.framework.mybatisplus.domain.BaseDomainImpl;
import com.peas.platform.framework.mybatisplus.po.BasePo;
import com.peas.platform.framework.mybatisplus.repository.BaseRepository;
import com.peas.platform.module.icims.base.mdm.adapter.repository.FileRepository;
import com.peas.platform.module.icims.base.mdm.adapter.repository.po.FilePo;
import com.peas.platform.module.icims.base.mdm.domain.FileDomain;
import com.peas.platform.module.icims.base.mdm.dto.FileDto;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

@Component
public class FileDomainImpl extends BaseDomainImpl<FileDto, FilePo> implements FileDomain {

    @Resource
    private FileRepository fileRepository;

    @Override
    public BaseRepository<FilePo> getMapper() {
        return fileRepository;
    }

    @Override
    public Class<? extends BaseRepository<FilePo>> getRepositoryClass() {
        return FileRepository.class;
    }

    private void checkFile(FileDto dto) {
        Long userId = Long.valueOf(RequestContextUtil.getCurrentUserId(true));
        FileDto c = new FileDto();
        c.setUploader(userId);
        c.setParentId(dto.getParentId());
        List<FileDto> list = this.findFileListByDir(OrderItem.desc("id"), c);
        Assert.isTrue(list.size() <= 500, "一个目录下最多可以上传500个文件，请先清理该目录");
        long count = list.stream().filter(attachmentPo -> StrUtil.equalsIgnoreCase(dto.getFileName(), attachmentPo.getFileName())).count();
        Assert.equals(count, 1L, "已经存在名为[" + dto.getFileName() + "]的文件/文件夹");
    }

    @Transactional
    @Override
    public int save(FileDto dto) {
        int result = super.save(dto);
        this.checkFile(dto);
        return result;
    }

    @Transactional
    @Override
    public int updateById(FileDto dto) {
        int result = super.updateById(dto);
        this.checkFile(dto);
        return result;
    }

    @Transactional
    @Override
    public int removeById(Serializable id) {
        FileDto dto = this.getById(id);
        Assert.isTrue(dto.getReferences() == 0, "附件[" + dto.getFileName() + "]已经被其他单据引用，无法删除");
        int result = super.removeById(id);
        List<FileDto> list = this.listByField("parentId", id);
        CollUtil.forEach(list, (CollUtil.Consumer<FileDto>) (value, index) -> FileDomainImpl.this.removeById(value.getId()));
        return result;
    }

    @Override
    public List<FileDto> findFileListByDir(OrderItem order, FileDto condition) {
        if (condition == null) {
            condition = new FileDto();
        }
        if (condition.getUploader() == null) {
            Long userId = Long.valueOf(RequestContextUtil.getCurrentUserId(true));
            condition.setUploader(userId);
        }
        QueryWrapper<FilePo> wrapper = super.buildWrapper(condition);
        if (condition.getParentId() == null) {
            wrapper.isNull("parent_id");
        }
        Page<FilePo> p = Page.of(1, 1000);
        List<OrderItem> list = new ArrayList<>();
        list.add(OrderItem.asc("attachment_type"));
        if (order != null) {
            Field field = ClassUtil.getDeclaredField(FilePo.class, order.getColumn());
            if (field == null) {
                field = ClassUtil.getDeclaredField(BasePo.class, order.getColumn());
            }
            Assert.notNull(field, "找不到属性:" + order.getColumn());
            TableId ti = field.getAnnotation(TableId.class);
            TableField tf = field.getAnnotation(TableField.class);
            String column = ti != null ? ti.value() : tf.value();
            OrderItem o = order.isAsc() ? OrderItem.asc(column) : OrderItem.desc(column);
            list.add(o);
        }
        p.setOrders(list);
        List<FilePo> pos = getMapper().selectList(p, wrapper);
        return BeanUtil.copyToList(pos, FileDto.class);
    }

}
